var debug = true;
var OpenLayers = OpenLayers;  // To fool JSLint.
var vvg = vvg;

OpenLayers.ProxyHost = '/cgi-bin/proxy.cgi?url=';
//OpenLayers.ProxyHost = '/geoserver/rest/proxy?url=';

// Pink tile avoidance.
OpenLayers.IMAGE_RELOAD_ATTEMPTS = 5;
// Make OL compute scale according to WMS spec.
OpenLayers.DOTS_PER_INCH = 25.4 / 0.28;

var map;
var drawControl;

var projections = {
	map:  {srsName: 'EPSG:900913'},	// Map is in spherical mercator = Google.
	display: {srsName: 'EPSG:4326'}		// Display is in WGS84 lat/lon.
};
var projection;
for (projection in projections) {
	projections[projection].olProjection = new OpenLayers.Projection(projections[projection].srsName);
}
var victoria = new OpenLayers.Bounds(
	141.0, -39.0,
	150.1, -34.0
);
victoria.transform(projections.display.olProjection, projections.map.olProjection);

var urls = {
	wms : {
		ffsr:	'http://siss.versi.edu.au/geoserver/wms?service=WMS',
		ubs:	'http://maps.ubspatial.com.au/groundwater/wms?service=WMS'
	},
	wfs : {
		ffsr:	'http://siss.versi.edu.au/geoserver/wfs?service=WFS',
		ubs:	'http://maps.ubspatial.com.au:8000/geoserver/wfs?service=WFS',
		loc:	'http://localhost:8080/geoserver/wfs?service=WFS'
	}
};
var layers = {
	gmap: {},
	osgeo: {},
	draw: {},
	features: {},
	wms: {
		ffsr: {},
		ubs: {}
	},
	wfs: {
		ffsr: {},
		ubs: {}
	}
};

function init() {
	vvg.myDataStore = vvg.lib.dataStoreAqWl;
	//vvg.myDataStore = vvg.lib.dataStoreAq;
	//vvg.myDataStore = vvg.lib.dataStoreWl;
	
	var mapOptions = {
		projection: projections.map.olProjection,
		displayProjection: projections.display.olProjection,
		units: 'm',
		maxResolution: 156543.0339,
		maxExtent: victoria,
		//numZoomLevels: 10,
		//maxZoomLevel: 18,
		//minZoomLevel: 8,
		controls: []
	};
	map = new OpenLayers.Map('map', mapOptions);

	// Create Google layer.
	layers.gmap = new OpenLayers.Layer.Google('Google Streets', // The default.
		{numZoomLevels: 20}
	);
	
	// Create OSGeo wms layer.
	layers.osgeo = new OpenLayers.Layer.WMS('OSGeo vmap0',
		'http://vmap0.tiles.osgeo.org/wms/vmap0?', 
		{
			layers: 'basic',
			isBaseLayer: true,
			visibility: true
		}
	);
	
	// Create FFSR sites layer.
	layers.wms.ffsr = new OpenLayers.Layer.WMS('FFSR sites', 
		urls.wms.ffsr, 
		{
			layers: 'dbo_sites', 
			//layers: 'vvg_bores', 
			transparent: true,
			isBaseLayer: false, 
			singleTile: true, 
			opacity: 0.6,
			visibility: true
		}
	);
	// Create groundwater bores layer.
	layers.wms.ubs = new OpenLayers.Layer.WMS('Bores', 
		urls.wms.ubs, 
		{
			layers: 'groundwater_bores,other_bores', 
			transparent: true,
			isBaseLayer: false, 
			singleTile: true, 
			opacity: 0.6,
			visibility: true
		}
	);

	// Create VeRSI-SISS FFSR WFS layers.
	layers.wfs.ffsr.borehole = new OpenLayers.Layer.Vector('FFSR WFS', {
		strategies: [new OpenLayers.Strategy.BBOX()],
		protocol: new OpenLayers.Protocol.WFS({
			url: urls.wfs.ffsr,
			featureType: 'Borehole',
			//geometryName: 'collarLocation',
			//geometryName: 'BoreholeCollar',
			//geometryName: 'location',
			//geometryName: 'Point',
			//featureNS: 'http://www.openplans.org/topp',
			extractAttributes : true,
			maxFeatures: 1000,
			srsName: projections.map.srsName,
			version: '1.1.0'
		})
	});        
	layers.wfs.ffsr.waterwell = new OpenLayers.Layer.Vector('FFSR WFS', {
		strategies: [new OpenLayers.Strategy.BBOX()],
		protocol: new OpenLayers.Protocol.WFS({
			url: urls.wfs.ffsr,
			featureType: 'WaterWell',
			//geometryName: 'sa:position',
			featurePrefix: 'gwml',
			featureNS: 'http://www.nrcan.gc.ca/xml/gwml/1',
			extractAttributes : true,
			maxFeatures: 10,
			srsName: projections.map.srsName,
			version: '1.1.0'
		})
	});        

	// Create UBSpatial SISS WFS layers.
	layers.wfs.ubs.borehole = new OpenLayers.Layer.Vector('UBS WFS', {
		strategies: [new OpenLayers.Strategy.BBOX()],
		protocol: new OpenLayers.Protocol.WFS({
			url: urls.wfs.ubs,
			featureType: 'Borehole',
			//geometryName: 'collarLocation',
			//geometryName: 'BoreholeCollar',
			//geometryName: 'location',
			//geometryName: 'Point',
			//featureNS: 'http://www.openplans.org/topp',
			extractAttributes : true,
			maxFeatures: 100,
			srsName: projections.map.srsName,
			version: '1.1.0'
		})
	});        
	layers.wfs.ubs.waterwell = new OpenLayers.Layer.Vector('UBS WFS', {
		strategies: [new OpenLayers.Strategy.BBOX()],
		protocol: new OpenLayers.Protocol.WFS({
			url: urls.wfs.ubs,
			featureType: 'WaterWell',
			//geometryName: 'collarLocation',
			//geometryName: 'BoreholeCollar',
			//geometryName: 'location',
			//geometryName: 'Point',
			//featureNS: 'http://www.openplans.org/topp',
			extractAttributes : true,
			maxFeatures: 10,
			srsName: projections.map.srsName,
			version: '1.1.0'
		})
	});        

	// Create drawing and feature layers.
	layers.draw = new OpenLayers.Layer.Vector('Line');
	layers.features = new OpenLayers.Layer.Vector('Transect features');
	
	// Add layers to map.
	//map.addLayer(layers.gmap);
	map.addLayer(layers.osgeo);
	map.addLayer(layers.draw);
	map.addLayer(layers.features);
	
	map.addLayer(layers.wms.ubs);
	//map.addLayer(layers.wms.ffsr);
	map.addLayer(vvg.myDataStore.layerAll());

	// Build up all controls.
	map.addControl(new OpenLayers.Control.PanZoomBar({
		position: new OpenLayers.Pixel(2, 15)
	}));
	map.addControl(new OpenLayers.Control.Navigation());
	map.addControl(new OpenLayers.Control.LayerSwitcher());
	map.addControl(new OpenLayers.Control.Scale($('scale')));
	map.addControl(new OpenLayers.Control.MousePosition({element: $('location')}));

	drawControl = new OpenLayers.Control.DrawFeature(layers.draw, OpenLayers.Handler.Path);
	drawControl.deactivate();
	map.addControl(drawControl);
	
	map.zoomToExtent(victoria);
}
	
// Sets the HTML provided into the nodelist element.
function setHTML(response) {
	document.getElementById('nodelist').innerHTML = response.responseText;
}
function setHTMLText(text) {
	document.getElementById('nodelist').innerHTML = text;
}

function getFeatureConnectionLayer(records, line) {
	var layer;
	var startPoint;
	var dx = 0.0, dy =0.0, len = 0.0;
	var lineStringFeatures = [];
	var i;
	var ratio = 0.0;
	var basePoint;
	var lineString;
	
	layer = new OpenLayers.Layer.Vector('Distance lines',{
		projection: projections.map.olProjection,
		isBaseLayer: false,
		visibility: true
	});
	layer.addFeatures([new OpenLayers.Feature.Vector(line)]);  // Add the selection line.
	startPoint = line.components[0];
	dx = line.components[1].x-startPoint.x;
	dy = line.components[1].y-startPoint.y;
	len = startPoint.distanceTo(line.components[1]);
	for (i in records) {
		ratio = records[i].M/len;
		if (0.0<=ratio && ratio<=1.0) {
			basePoint = new OpenLayers.Geometry.Point(startPoint.x+ratio*dx, startPoint.y+ratio*dy);
			lineString = new OpenLayers.Geometry.LineString([basePoint, records[i].point]);
			lineStringFeatures.push(new OpenLayers.Feature.Vector(lineString));
		}
	}
	layer.addFeatures(lineStringFeatures);
	return layer;
}

function showAllBores() {
	// This is just for debugging purposes once the request has completed.
	// All real action should be in the callback function below.
	var bores = vvg.myBoreTransect.getBores();
	alert(bores.length+' bores');
	var filteredBores = vvg.myBoreTransect.getBoresFiltered({uniqueProperty: 'label'});
	var s = '';
	var i;
	for (i = 0; i < filteredBores.length; i += 1) {
		s += Math.round(filteredBores[i].elevation*10)/10+', ';
	}
	alert('Elevations: '+s);
		
	alert(vvg.myBoreTransect.asString(200));
}

function toggleDraw(element) {
	if (element.checked) {
		layers.draw.destroyFeatures();
		layers.features.destroyFeatures();
		drawControl.activate();
	} else {
		drawControl.deactivate();
		var transect = vvg.lib.transect(layers.draw);
		var distance = {value: 5000, units: 'm'};
		//var distance = {value: 0.05000, units: 'degrees'};
		layers.draw.destroyFeatures();
		layers.draw.addFeatures([new OpenLayers.Feature.Vector(transect.lineString)]);  // Add the selected transect.
		
		vvg.myDataStore.requestTransect(
			transect,
			distance,
			function (params) {
				setHTMLText('End of WFS query after '+Math.round(params.duration/1000)+' sec.');
				if (debug) {alert('Completed after '+Math.round(params.duration/1000)+' sec.');}
				vvg.myDataStore.fillLayerFromTransect(layers.features, {simplifyByAttribute: 'bore_id'});
				vvg.myBoreTransect = vvg.myDataStore.boreTransect();
				// drawPanel(vvg.myBoreTransect);
				// alert(vvg.myBoreTransect.asString());
			}			
		);
		if (debug) {layers.draw.addFeatures([new OpenLayers.Feature.Vector(transect.distancePolygon(distance))]);}
		setHTMLText('Start of WFS query ');
	}
}
